﻿#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <dlfcn.h>
#include <sys/socket.h>    // for socket
#include <netinet/in.h>    // for sockaddr_in
#include <stdio.h>        // for printf
#include <stdlib.h>        // for exit
#include <string.h>        // for bzero
#include <wait.h>
#include <errno.h>
#include <sys/types.h>
#include <memory.h>
#include <arpa/inet.h>

#include "tpool.h"
#include "common.h"

#define PORT 4562
int s; //全局变量 ， 存储套接字描述符
int login_ret = 0;//登陆结果

void Shutdown(int iSignum)
{
	//mysql_free_result(g_res); // 释放结果集	
	//mysql_close(g_conn); // 关闭链接
	//SingleList_Destroy(socket_list, closeSocket);
	//close(sc);
	close(s);
	tpool_destroy();
}

void *process_heartbeat(void* socket)
{
	int s;
	s = *((int*)socket);
	for (;;)
	{
		sleep(10);
		char heartbeat_bufer[4] = { '\0' };
		sprintf(heartbeat_bufer, "S\n");
		if (write(s, heartbeat_bufer, strlen(heartbeat_bufer)) == -1)
		{
			printf("发送心跳包失败!\n");
			exit(1);
		}
	}	
}

void *process_recv(void* socket)
{
	int s;
	s = *((int*)socket);
	char recv_buffer[1024] = { '\0' };
	for (;;)
	{		
		memset(recv_buffer, 0x00, 1024);
		if (recv(s, recv_buffer, 1024, 0) <= 0)
		{
			printf("接收登录响应失败!\n");
			exit(1);
		}
		printf("recv buff=%s strlen buff=%d\n", recv_buffer, (int)strlen(recv_buffer));
		if (strstr(recv_buffer, "Login Successful") && strlen(recv_buffer) == 16)
		{
			printf("Login Successful\n");
			login_ret = 1;
            		sendGetAPInfoResponse(s);
		}
        else
        {
            char buffer_tmp[1024] = { '\0' };
            char* p = recv_buffer + strlen(TAG_START) + 1;
            int check_index;
            check_index = indexOf(recv_buffer, "check=");
            if (check_index != -1)
            {
                strncpy(buffer_tmp, p, check_index - (strlen(TAG_START) + 2));
                //printf("buffer_tmp=|%s|\n", buffer_tmp);
                int check_checkcode = getCode(buffer_tmp);
                char recv_checkcode[8] = { '\0' };
                Get_Info("check=", recv_checkcode, recv_buffer);
                if (check_checkcode != atoi(recv_checkcode))
                {
                    printf("revc check code is invalid!\n");
                    continue;
                }
            }
            else
            {
                if (2 != strlen(recv_buffer))
                {   
                    printf("recv invalid packet!\n");
                    continue;
                }
            }

            int tag_begin_index = strlen(TAG_START) + 1;
            char tmp_buffer[1024] = { '\0' };
            substring(tmp_buffer, recv_buffer, tag_begin_index, 1024);
            int tag_end_index = indexOf(tmp_buffer, " ");
            char tag_str[64] = { '\0' };
            if (tag_end_index != -1)
            {
                substring(tag_str, tmp_buffer, 0, tag_end_index);
                printf("tag_str=|%s|\n", tag_str);
            }
            else
            {
                printf("recv invalid packet!\n");
                continue;
            }

            if (0 == strcmp(tag_str, "ap_get"))
            {
                sendGetAPInfoResponse(s);
            }
            else if (0 == strcmp(tag_str, "AP_Config"))
            {
                AP_INFO ap_info;
                memset(&ap_info, 0x00, sizeof(AP_INFO));
                recvAPConfigRequest(recv_buffer, &ap_info);
                printf("recv ap config:tp1=%d,ch1=%d,ssid1=%s,encry1=%d,key1=%s,ssid2=%s,encry2=%d,key2=%s\n",ap_info.tp1,ap_info.ch1,ap_info.ssid1,ap_info.encry1,ap_info.key1,ap_info.ssid2,ap_info.encry2,ap_info.key2);
		set_wireless_config(ap_info);
            }
            else if (0 == strcmp(tag_str, "AP_Upgrade"))
            {
                char filepath[256] = { '\0' };
                Get_Info("file=", filepath, recv_buffer);
                char md5check[128] = { '\0' };
                Get_Info("md5=", md5check, recv_buffer);
                printf("AP_Upgrade filepath=%s,md5=%s\n", filepath, md5check);
            }
            else if (0 == strcmp(tag_str, "sta_get"))
            {
                sendStaListResponse(s);
            }
        }
	}
}

int 
main(int arg, char *argv[])
{	
	int pid = fork();

	if (pid < 0)
	{
		printf("Fork Error!");
	}
	else if (pid != 0)
	{
		printf("Father Process exit!");
		exit(0);
	}

    if (tpool_create(50) != 0) {
        printf("tpool_create failed\n");
        exit(1);
	}

	struct sockaddr_in server_addr;
	int err;
	//char server_ip[50] = "";
	/********************socket()*********************/
	s = socket(AF_INET, SOCK_STREAM, 0);
	if (s<0)
	{
		printf("client : create socket error\n");
		return 1;
	}

	/*******************connect()*********************/
	//设置服务器地址结构，准备连接到服务器
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	/*将用户数入对额字符串类型的IP格式转化为整型数据*/
	//inet_pton(AF_INET,argv[1],&server_addr.sin_addr.s_addr);
	//printf("please input server ip address : \n");
	//read(0, server_ip, 50);
	//err = inet_pton(AF_INET,server_ip,&server_addr.sin_addr.s_addr);
	//server_addr.sin_addr.s_addr = inet_addr("121.42.15.146");
	server_addr.sin_addr.s_addr = inet_addr("114.215.154.213");

	do
	{
		printf("try to connect server!\n");
		sleep(10);
		err = connect(s, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
	} while (err != 0);

	printf("connect to server!\n");

	if (tpool_add_work(process_recv, (void *)&s) == 0)
	{
		printf("add process_recv successfully!\n");
	}
	else
	{
		close(s);
		printf("add process_recv failed!\n");
		return -1;
	}

	do
	{
		if (login_ret == 1)
		{
			break;
		}
		sendLoginRequest(s,argv[1]);
		sleep(30);
	} while (!login_ret);

	if (tpool_add_work(process_heartbeat, (void *)&s) == 0)
	{
		printf("add process_heartbeat successfully!\n");
	}
	else
	{
		close(s);
		printf("add process_heartbeat failed!\n");
		return -1;
	}

	signal(SIGHUP, Shutdown);
	signal(SIGINT, Shutdown);
	signal(SIGTERM, Shutdown);
	//signal(SIGSEGV, Shutdown);
	signal(SIGKILL, Shutdown);

	for (;;)
	{
		sleep(1);
	}
	
    return 0;
}                                       
